
class DingManHua extends ComicSource {
    // 注意: 标记为[可选]的字段如果不使用应删除

    // 源名称
    name = "顶漫画"

    // 源的唯一标识
    key = "DingManHua"

    version = "1.0.1"

    minAppVersion = "1.4.0"

    // 更新链接
    url = "https://gitee.com/cmj_xxgg/comic_yuan/edit/master/%E9%A1%B6%E6%BC%AB%E7%94%BB.js"

    /**
     * [可选] 初始化函数
     */
    init() {
        this.baseUrl = "https://dingmanhua.com/";
    }


    // 探索页面列表
    explore = [
        {
            // 页面标题
            // 标题用于标识页面，应保持唯一
            title: "顶漫画",

            /// multiPartPage（多分区页面）或multiPageComicList（多页漫画列表）或mixed（混合类型）
            type: "singlePageWithMultiPart",

            // 分区列表
            load: async (page) => {

                // 1.获取网页内容
                let res = await Network.get(this.baseUrl);

                if (res.status !== 200) {
                    throw `Invalid status code: ${res.status}`
                }

                // 2. 解析文档
                let doc = new HtmlDocument(res.body);

                // 3. 通用解析单元函数
                function parseItem(el) {
                    // 获取id /comic/8608.html
                    let id = el.querySelector("a").attributes.href.replace('/comic/', '').replace('.html', '');
                    // 获取封面
                    let imgEl = el.querySelector("img");
                    let cover = imgEl.attributes['data-src'];
                    // 获取标题
                    let title = el.querySelector("h3").text.trim();
                    return new Comic({ id, title, cover });
                }

                // 4. 获取最近更新
                let newss = [];
                let newssList = doc.querySelectorAll("div.card-main")[0];
                if (newssList) {
                    let items = newssList.querySelectorAll("div.card-content");
                    for (let el of items) {
                        newss.push(parseItem(el));
                    }
                }

                // 5. 获取热门漫画
                let hot = [];
                let hotList = doc.querySelectorAll("div.card-main")[1];
                if (hotList) {
                    let items = hotList.querySelectorAll("div.card-content");
                    for (let el of items) {
                        hot.push(parseItem(el));
                    }
                }

                // 6. 获取随机推荐
                let rGood = [];
                let rGoodList = doc.querySelectorAll("div.card-main")[2];
                if (rGoodList) {
                    let items = rGoodList.querySelectorAll("div.card-content");
                    for (let el of items) {
                        rGood.push(parseItem(el));
                    }
                }

                // 7. 清理并返回
                doc.dispose();
                return {
                    "最近更新": newss,
                    "热门漫画": hot,
                    "随机推荐": rGood
                };
            },
        }
    ]

    // 分类
    category = {
        /// 分类页面标题，用于标识页面，应保持唯一
        title: "GoDamh",
        parts: [
            {
                // 分区标题
                name: "分类",

                // fixed（固定）或random（随机）或dynamic（动态）
                // 如果是random类型，需要提供`randomNumber`字段，表示同时显示的漫画数量
                // 如果是dynamic类型，需要提供`loader`字段，表示加载漫画的函数
                type: "fixed",

                categories: ["悬疑","欢乐","搞笑","玄幻","冒险","爱情","百合","推理","热血","异界","轻改","奇幻","校园","妹控","生活","竞技","同人","伪娘","东方","美食","格斗","战争","舰娘","治愈","魔幻","职场","性转","萌系","后宫","节操","魔法","科幻","穿越","仙侠","都市","异能","网游","短篇","女主","恐怖","重生","日常","侦探","言情","生存","武侠","系统","励志","末世","转生","长篇","修仙","末日","灵异","游戏","爱情","销毁","病娇","音乐","爆笑","机战","复仇","舞蹈","战斗","逆袭","历史","恋爱","养成","四格","宫廷","诡异","惊悚","耽美","彩色","其他","TL","宅系","FATE","C103","C105","歓楽向","爱情","冒险","神鬼","轻小说","格鬥","後宫"],

                itemType: "category",

                // 若提供, 数量需要和`categories`一致, `categoryComics.load`方法将会收到此参数
                categoryParams: ["1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35","36","37","38","39","40","41","42","43","44","45","46","47","48","49","50","51","52","53","54","55","56","57","58","59","60","61","62","63","64","65","66","67","68","69","70","71","72","73","74","75","76","77","78","79","80","81","82","83","84","85","86","87"]
             }
        ],
        // 启用排行榜页面
        enableRankingPage: false,
    }

    /// 分类漫画加载相关
    categoryComics = {
        /**
         * 加载分类漫画
         * @param category {string} - category name
         * @param param {string?} - category param
         * @param options {string[]} - options from optionList
         * @param page {number} - page number
         * @returns {Promise<{comics: Comic[], maxPage: number}>}
         */
        load: async (category, param, options, page) => {

            // 分类网址
            // https://dingmanhua.com/sort?category=0&tag=0

            let url = `${this.baseUrl}/sort?category=0&tag=${param}&page=${page}`;
            // 发起请求
            let res = await Network.get(url);
            if (res.status !== 200) {
                throw `Invalid status code: ${res.status}`;
            }
            // 解析 HTML
            let document = new HtmlDocument(res.body);

            // 获取最大页数
            // 首先找到aria-label="下一頁"的a标签
            let maxPage = document.querySelector('.page-number').text.replace('1 of ', '');
            if (maxPage){
                maxPage = parseInt(maxPage);
            }else{
                maxPage = 1;
            }

            // 获取漫画列表
            let mangaList = [];
            let rows = document.querySelectorAll(".card-content");
            for (let row of rows) {
                    // 获取id /comic/8608.html
                    let id = row.querySelector("a").attributes.href.replace('/comic/', '').replace('.html', '');
                    // 获取封面
                    let imgEl = row.querySelector("img");
                    let cover = imgEl.attributes['data-src'];
                    // 获取标题
                    let title = row.querySelector("h3").text.trim();
                    // 获取分类
                    let categorys = category;
                    // 构建漫画对象
                    let manga = {
                        id: id,
                        title: title,
                        cover: cover, // 默认封面
                        tags: [categorys],
                        description: ` `
                    };

                    mangaList.push(manga);
            }

            return {
                comics: mangaList,
                maxPage: maxPage
            };
        },
        // // 为分类漫画加载提供选项
        // optionList: [
        //     {
        //         // 单个选项使用`-`分隔值和文本，左侧为值，右侧为文本
        //         options: [
        //             "newToOld-New to Old",
        //             "oldToNew-Old to New"
        //         ],
        //         // [可选] {string[]} - 仅当值不在列表中时显示此选项
        //         notShowWhen: null,
        //         // [可选] {string[]} - 仅当值在列表中时显示此选项
        //         showWhen: null
        //     }
        // ],
        // ranking: { // 排行榜
        //     // For a single option, use `-` to separate the value and text, left for value, right for text
        //     options: [
        //         "day-Day",
        //         "week-Week"
        //     ],
        //     /**
        //      * 加载排行榜漫画
        //      * @param option {string} - option from optionList
        //      * @param page {number} - page number
        //      * @returns {Promise<{comics: Comic[], maxPage: number}>}
        //      */
        //     load: async (option, page) => {
        //         /*
        //         ```
        //         let data = JSON.parse((await Network.get('...')).body)
        //         let maxPage = data.maxPage

        //         function parseComic(comic) {
        //             // ...

        //             return new Comic({
        //                 id: id,
        //                 title: title,
        //                 subTitle: author,
        //                 cover: cover,
        //                 tags: tags,
        //                 description: description
        //             })
        //         }

        //         return {
        //             comics: data.list.map(parseComic),
        //             maxPage: maxPage
        //         }
        //         ```
        //         */
        //     }
        // }
    }

    /// 搜索相关
    search = {
        /**
         * 加载搜索结果
         * @param keyword {string}
         * @param options {string[]} - options from optionList
         * @param page {number}
         * @returns {Promise<{comics: Comic[], maxPage: number}>}
         */
        load: async (keyword, options, page) => {
            // 搜索网址 https://dingmanhua.com/search?query=%E8%B6%85%E7%BA%A7&page=2
            let url = `${this.baseUrl}/search?query=${keyword}&page=${page}`;

            let res = await Network.get(url);

            if (res.status !== 200) {throw `Invalid status code: ${res.status}`;}

            let document = new HtmlDocument(res.body);
    
            // 获取最大页数
            // 首先找到aria-label="下一頁"的a标签
            let maxPage = document.querySelector('.page-number').text.replace('1 of ', '');
            if (maxPage){
                maxPage = parseInt(maxPage);
            }else{
                maxPage = 1;
            }

            // 获取漫画列表
            let mangaList = [];
            let rows = document.querySelectorAll(".card-content");
            for (let row of rows) {
                    // 获取id /comic/8608.html
                    let id = row.querySelector("a").attributes.href.replace('/comic/', '').replace('.html', '');
                    // 获取封面
                    let imgEl = row.querySelector("img");
                    let cover = imgEl.attributes['data-src'];
                    // 获取标题
                    let title = row.querySelector("h3").text.trim();
                    // 获取分类
                    let categorys = '';
                    // 构建漫画对象
                    let manga = {
                        id: id,
                        title: title,
                        cover: cover, // 默认封面
                        tags: [categorys],
                        description: ` `
                    };

                    mangaList.push(manga);
            }

            return {
                comics: mangaList,
                maxPage: maxPage
            };
        },

        /**
         * 使用下一页令牌加载搜索结果。
         * The field will be ignored if `load` function is implemented.
         * @param keyword {string}
         * @param options {(string)[]} - options from optionList
         * @param next {string | null}
         * @returns {Promise<{comics: Comic[], maxPage: number}>}
         */
        loadNext: async (keyword, options, next) => {
        },

        // 为搜索提供选项
        optionList: [
        ],

        // 启用标签建议
        enableTagsSuggestions: false,
    }

    // 收藏相关
    favorites = {
        // 是否支持多文件夹
        multiFolder: false,
        /**
         * 添加或删除收藏。
         * 抛出`Login expired`表示登录过期，应用将自动重新登录并重新添加/删除收藏
         * @param comicId {string}
         * @param folderId {string}
         * @param isAdding {boolean} - true for add, false for delete
         * @param favoriteId {string?} - [Comic.favoriteId]
         * @returns {Promise<any>} - return any value to indicate success
         */
        addOrDelFavorite: async (comicId, folderId, isAdding, favoriteId) => {
            /*
            ```
            let res = await Network.post('...')
            if (res.status === 401) {
                throw `Login expired`;
            }
            return 'ok'
            ```
            */
        },
        /**
         * 加载收藏文件夹。
         * throw `Login expired` to indicate login expired, App will automatically re-login retry.
         * if comicId is not null, return favorite folders which contains the comic.
         * @param comicId {string?}
         * @returns {Promise<{folders: {[p: string]: string}, favorited: string[]}>} - `folders` is a map of folder id to folder name, `favorited` is a list of folder id which contains the comic
         */
        loadFolders: async (comicId) => {
            /*
            ```
            let data = JSON.parse((await Network.get('...')).body)

            let folders = {}

            data.folders.forEach((f) => {
                folders[f.id] = f.name
            })

            return {
                folders: folders,
                favorited: data.favorited
            }
            ```
            */
        },
        /**
         * 添加文件夹
         * @param name {string}
         * @returns {Promise<any>} - return any value to indicate success
         */
        addFolder: async (name) => {
            /*
            ```
            let res = await Network.post('...')
            if (res.status === 401) {
                throw `Login expired`;
            }
            return 'ok'
            ```
            */
        },
        /**
         * 删除文件夹
         * @param folderId {string}
         * @returns {Promise<void>} - return any value to indicate success
         */
        deleteFolder: async (folderId) => {
            /*
            ```
            let res = await Network.delete('...')
            if (res.status === 401) {
                throw `Login expired`;
            }
            return 'ok'
            ```
            */
        },
        /**
         * 加载文件夹中的漫画
         * throw `Login expired` to indicate login expired, App will automatically re-login retry.
         * @param page {number}
         * @param folder {string?} - folder id, null for non-multi-folder
         * @returns {Promise<{comics: Comic[], maxPage: number}>}
         */
        loadComics: async (page, folder) => {
            /*
            ```
            let data = JSON.parse((await Network.get('...')).body)
            let maxPage = data.maxPage

            function parseComic(comic) {
                // ...

                return new Comic{
                    id: id,
                    title: title,
                    subTitle: author,
                    cover: cover,
                    tags: tags,
                    description: description
                }
            }

            return {
                comics: data.list.map(parseComic),
                maxPage: maxPage
            }
            ```
            */
        },
        /**
         * 使用下一页令牌加载漫画
         * @param next {string | null} - next page token, null for first page
         * @param folder {string}
         * @returns {Promise<{comics: Comic[], next: string?}>}
         */
        loadNext: async (next, folder) => {

        },
        /**
         * 如果漫画源只允许一个漫画在一个文件夹中，设置为true。
         */
        singleFolderForSingleComic: false,
    }

    /// 单部漫画相关
    comic = {
        /**
         * 加载漫画信息
         * @param id {string}
         * @returns {Promise<ComicDetails>}
         */
        loadInfo: async (id) => {
            // 详情网页 https://dingmanhua.com/comic/298.html
            let url = `${this.baseUrl}/comic/${id}.html`;
            let res = await Network.get(url);
            if (res.status !== 200) {throw `Invalid status code: ${res.status}`;}
            let document = new HtmlDocument(res.body);

            // 漫画标题
            let title = document.querySelector(".info > h1").text.trim();

            // 漫画封面
            let cover = document.querySelector("div.container-fluid");
            if(cover){
                cover = cover.querySelector("img").attributes['data-src'];
            }

            // 漫画描述
            let description = document.querySelector("p.description").text.trim();

            // 漫画作者
            let author = document.querySelector("div.author").text.trim().replace("作者：", "");

            // 漫画标签
            let tags = [];
            document.querySelectorAll("div.author > a").forEach(tag => {
                tags.push(tag.text.trim());
            });

            // 更新时间
            let updateTime = '';

            // 漫画章节
            // 获取章节json数据 https://dingmanhua.com/comic/298
            let chapterListUrl = `https://dingmanhua.com/comic/${id}`;
            let chapterRes = await Network.post(chapterListUrl);
            if (chapterRes.status !== 200) {throw `Invalid status code: ${chapterRes.status}`;}
            let chapterData = JSON.parse(chapterRes.body);
            /**
                {
                    "code": 0,
                    "message": "",
                    "data": {
                        "chapters": [
                            {
                                "id": 601479,
                                "contentId": 298,
                                "chapterName": "第268话 坦白！魔功传承者！",
                                "chapterNum": 130,
                                "chapterPath": "2d9ce444-eb37-4322-bba8-9570f28c6132",
                                "createdAt": "2025-08-05 09:08:14",
                                "updatedAt": "2025-08-05 09:08:16"
                            },
                            {
                                "id": 599839,
                                "contentId": 298,
                                "chapterName": "第267话 刺杀",
                                "chapterNum": 128,
                                "chapterPath": "886bf075-0ab6-47bd-bac7-92e0778b9a90",
                                "createdAt": "2025-07-31 07:03:53",
                                "updatedAt": "2025-08-05 09:08:16"
                            },
             */
            // 这里的id是章节id chapterName是章节名 updatedAt是更新时间

            let chapters = new Map();
            // 遍历 chapters 数组
            if (chapterData.data && chapterData.data.chapters) {
                updateTime = chapterData.data.chapters[0]?.updatedAt;
                updateTime = updateTime.split(' ')[0]; // 只取日期部分

                for (const chapter of chapterData.data.chapters) {
                    const chapterId = chapter.id.toString();
                    const title = chapter.chapterName;
                    
                    // 如果 chapterId 和 title 都不为空，则添加到 Map 中
                    if (chapterId && title) {
                        chapters.set(chapterId, title);
                    }
                }
            }


            return {
                title: title,
                cover: cover,
                description: description,
                tags: {
                    "作者": [author],
                    "更新": [updateTime],
                    "标签": tags
                },
                chapters: chapters
            };
        },
        /**
         * 加载章节图片
         * @param comicId {string}
         * @param epId {string?}
         * @returns {Promise<{images: string[]}>}
         */
        loadEp: async (comicId, epId) => {
            /*
            ```
            return {
                // string[]
                images: images
            }
            ```
            */
            // 章节网址 https://dingmanhua.com/chapter/298-601479.html
            let url = `${this.baseUrl}/chapter/${comicId}-${epId}.html`;
            let res = await Network.get(url);
            if (res.status !== 200) {throw `Invalid status code: ${res.status}`;}
            let document = new HtmlDocument(res.body);

            // 获取文档中所有的 script 标签
            const scriptTags = document.querySelectorAll('script');
            let num = null;
            let pasd = null;

            // 遍历每个脚本标签
            for (const script of scriptTags) {
                const scriptContent = script.innerHTML;
                
                // 检查是否包含 num 变量定义
                if (scriptContent.includes('var num =')) {
                    // 使用正则表达式提取 num 的值
                    const numMatch = scriptContent.match(/var num\s*=\s*eval\("([^"]+)"\)/);
                    if (numMatch && numMatch[1]) {
                        num = parseInt(numMatch[1]);
                    }
                }
                
                // 检查是否包含 pasd 变量定义
                if (scriptContent.includes('var pasd =')) {
                    // 使用正则表达式提取 pasd 的值
                    const pasdMatch = scriptContent.match(/var pasd\s*=\s*"([^"]+)"/);
                    if (pasdMatch && pasdMatch[1]) {
                        pasd = pasdMatch[1];
                    }
                }
                
                // 如果已经找到两个值，可以提前退出循环
                if (num !== null && pasd !== null) {
                    break;
                }
            }

            // num是图片数量，pasd是图片地址前缀
            let images = [];
            for (let i = 1; i <= num; i++) {
                images.push(`${pasd}${i}.webp`);
            }

            return{
                images: images
            }

        },
        // {string?} - 正则表达式字符串，用于从用户输入中识别漫画ID
        idMatch: null,
        // 启用标签翻译
        enableTagsTranslate: false,
    }
}
